package de.uni_mannheim.informatik.ai.dame_ai.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;
@SuppressWarnings("serial")

/**
 * This Layout Container places a Component in it's center and changes it's size dynamically.
 * The contained Component will be displayed at the biggest size possible, but in a fix aspect ratio.
 * @author Martin Boelle
 */
public class CenterPanel extends JPanel {
	
	float aspectRatio;
	int padding;
	Component content;
	private BufferedImage imgTile;
	private BufferedImage imgBackGround;
	
	/**
	 * 
	 * Creates a CenterPanel which's background is filled by bgImage.</br>
	 * The image will be used as a tile to fill the background.</br>
	 * That means it will be repeated until the whole CenterPanel is filled.</br>
	 * The image will NOT be scaled.
	 * 
	 * @param The Component to be displayed.
	 * @param The aspect ratio in which the Component will be displayed. (width/height)
	 * @param The padding around the Component.
	 * @param bgImage the image which fills the background of the CenterPanel
	 */
	public CenterPanel(Component content, float aspectRatio, int padding, String bgImage){
		this.aspectRatio=aspectRatio;
		this.padding=padding;
		this.content=content;
		setLayout(null);		
		if(content!=null)
			add(content);
		if(bgImage!=null)
			try {
				imgTile=ImageIO.read(new File(bgImage));
			} catch (IOException e) {
				e.printStackTrace();
			}

		this.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				super.componentResized(e);
				adjustContentSize();
				adjustBackGroundSize();
			}
		});
	}
	
	public void setAspectRatio(float aspectRatio) {
		this.aspectRatio=aspectRatio;
		adjustContentSize();
		repaint();
	}
	
	
	/**
	 * @param The aspect ratio in which the Component will be displayed. (width/height)
	 * @param The padding around the Component.
	 */
	public CenterPanel(float aspectRatio, int padding, String bgImage){
		this(null, aspectRatio, padding, bgImage);
	}

	
	/**
	 * @param The Component to be displayed.
	 * @param The aspect ratio in which the Component will be displayed. (width/height)
	 * @param The padding around the Component.
	 */
	public CenterPanel(Component content, float aspectRatio, int padding){
		this(content, aspectRatio, padding, null);
	}
	
	@Override
	public void paintComponent(Graphics g1){
		super.paintComponent(g1);
		g1.drawImage(imgBackGround, 0, 0, null);
	}
	
	
	void adjustContentSize(){
		if(content!=null){
			int newWidth, newHeight;
			int posX=padding, posY=padding;
			if((int)(getHeight()*aspectRatio)>getWidth()){
				newWidth = getWidth()-2*padding;
				newHeight =  (int)(getWidth()/aspectRatio)-2*padding;
				posY=(getHeight()-newHeight)/2;
			}
		  else{
				newHeight =	getHeight()-2*padding;
				newWidth = (int)(getHeight()*aspectRatio)-2*padding;
				posX=(getWidth()-newWidth)/2;
			}
			content.setBounds(posX, posY, newWidth, newHeight);
		}
	}
	
	private void adjustBackGroundSize(){
	//if(imgComplete==null || getHeight() > imgComplete.getWidth() || getHeight() > imgBackGround.getHeight()){
		if(imgTile!=null) {
			imgBackGround=new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
			int repeatFactorX=(int) Math.ceil(((double)imgBackGround.getWidth())/imgTile.getWidth());
			int repeatFactorY=(int) Math.ceil(((double)imgBackGround.getHeight())/imgTile.getHeight());
			Graphics g=imgBackGround.getGraphics();
			for(int i=0;i<repeatFactorX;i++)
				for (int j=0; j<repeatFactorY;j++)
					g.drawImage(imgTile, i*imgTile.getWidth(), j*imgTile.getHeight(), null);
		}
	//}
	}
	
	/**
	 * @param cont the component that should be displayed inside of the CenterPanel.
	 */
	public void setContent(Component cont){
		if(this.content!=null)
			remove(this.content);
		this.content=cont;
		add(cont);
	}
}